[JS] 全面解析reduce()函數(二)


Posted by mike-hsieh on 2023-10-19

本文網址: https://mike.coderbridge.io/2023/10/19/how-to-use-reduce-in-javascript-2/

延續上一章節: [JS] 全面解析reduce()函數(一)

第二篇主要以實戰方式來記錄reduce可以使用於哪些場景,以下列出30個。

1. 陣列求和:

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15

2. 陣列求乘積:

const numbers = [1, 2, 3, 4];
const product = numbers.reduce((acc, curr) => acc * curr, 1);
console.log(product); // 24

3. 轉換成對象:

const data = [{id: 1, value: 'a'}, {id: 2, value: 'b'}];
const obj = data.reduce((acc, item) => {
    acc[item.id] = item.value;
    return acc;
}, {});
console.log(obj); // {1: 'a', 2: 'b'}

4. 統計陣列出現的屬性的數量:

const fruits = ['apple', 'banana', 'orange', 'apple', 'banana'];
const count = fruits.reduce((acc, fruit) => {
    acc[fruit] = (acc[fruit] || 0) + 1;
    return acc;
}, {});
console.log(count); // { apple: 2, banana: 2, orange: 1 }

5. 去重複:

const nums = [1, 2, 3, 2, 1, 4, 5];
const unique = nums.reduce((acc, num) => {
    if (!acc.includes(num)) {
        acc.push(num);
    }
    return acc;
}, []);
console.log(unique); // [1, 2, 3, 4, 5]

6. 攤平/扁平化陣列:

const arr2D = [[1, 2], [3, 4], [5, 6]];
const flat = arr2D.reduce((acc, curr) => acc.concat(curr), []);
console.log(flat); // [1, 2, 3, 4, 5, 6]

7. 找最大值:

const numbers = [10, 25, 65, 29, 71, 34];
const max = numbers.reduce((acc, curr) => (curr > acc ? curr : acc));
console.log(max); // 71

8. 找最小值:

const numbers = [10, 25, 65, 29, 71, 34];
const min = numbers.reduce((acc, curr) => (curr < acc ? curr : acc));
console.log(min); // 10

9. 串接字串:

const words = ['Hello', 'World', 'JavaScript', 'Rocks'];
const sentence = words.reduce((acc, word) => `${acc} ${word}`, '').trim();
console.log(sentence); // "Hello World JavaScript Rocks"

10. 組成新的陣列 (像 map):

const numbers = [1, 2, 3];
const doubled = numbers.reduce((acc, num) => {
    acc.push(num * 2);
    return acc;
}, []);
console.log(doubled); // [2, 4, 6]

11. 過濾並建立新陣列 (像 filter):

const numbers = [1, 2, 3, 4, 5];
const evens = numbers.reduce((acc, num) => {
    if (num % 2 === 0) acc.push(num);
    return acc;
}, []);
console.log(evens); // [2, 4]

12. 組合 map 和 filter:

const numbers = [1, 2, 3, 4, 5];
const doubledEvens = numbers.reduce((acc, num) => {
    if (num % 2 === 0) acc.push(num * 2);
    return acc;
}, []);
console.log(doubledEvens); // [4, 8]

13. 計算陣列中物件的某個屬性的總和:

const items = [
    { name: 'ball', price: 10 },
    { name: 'book', price: 20 },
    { name: 'pen', price: 5 }
];
const totalPrice = items.reduce((acc, item) => acc + item.price, 0);
console.log(totalPrice); // 35

14. 建立索引對應的對象:

const items = [
    { id: 'a', value: 10 },
    { id: 'b', value: 20 },
    { id: 'c', value: 5 }
];
const itemMap = items.reduce((acc, item) => {
    acc[item.id] = item.value;
    return acc;
}, {});
console.log(itemMap); // { a: 10, b: 20, c: 5 }

15. 轉置二維陣列:

const matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];
const transpose = matrix.reduce((acc, row) => row.map((_, i) => [...(acc[i] || []), row[i]]), []);
console.log(transpose); // [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

16. 合併多個陣列:

const arrays = [[1, 2], [3, 4], [5, 6]];
const merged = arrays.reduce((acc, curr) => acc.concat(curr), []);
console.log(merged); // [1, 2, 3, 4, 5, 6]

17. 資料分組GroupBy:

const people = [
    { name: 'John', age: 25 },
    { name: 'Jane', age: 30 },
    { name: 'Tom', age: 25 }
];
const groupByAge = people.reduce((acc, person) => {
    const age = person.age;
    if (!acc[age]) {
        acc[age] = [];
    }
    acc[age].push(person);
    return acc;
}, {});
console.log(groupByAge); // { '25': [{...}, {...}], '30': [{...}] }

18. 判斷所有元素是否符合條件:

const numbers = [1, 2, 3, 4, 5];
const allAboveZero = numbers.reduce((acc, num) => acc && num > 0, true);
console.log(allAboveZero); // true

19. 轉換為新物件格式:

const data = [
    { key: 'name', value: 'John' },
    { key: 'age', value: 25 }
];
const obj = data.reduce((acc, item) => {
    acc[item.key] = item.value;
    return acc;
}, {});
console.log(obj); // { name: 'John', age: 25 }

20. 尋找陣列中的某個物件:

const users = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Jane' },
    { id: 3, name: 'Tom' }
];
const user = users.reduce((acc, curr) => {
    if (curr.id === 2) {
        return curr;
    }
    return acc;
}, null);
console.log(user); // { id: 2, name: 'Jane' }

21. 計算資料的平均值:

const grades = [87, 94, 72, 60, 88];
const average = grades.reduce((acc, grade, index, array) => {
    acc += grade;
    if (index === array.length - 1) return acc / array.length;  // 表示最後一筆,就要除於總長度
    return acc;  // 表示還沒跑完
}, 0);
console.log(average); // 80.2

22. 建立鍊接對象:

const pairs = [['a', 1], ['b', 2], ['c', 3]];
const linkedObj = pairs.reduce((acc, [key, value]) => {
    acc[key] = value;
    return acc;
}, {});
console.log(linkedObj); // { a: 1, b: 2, c: 3 }

23. 轉換字串成對象:

const queryString = 'key=value&key2=value2';
const params = queryString.split('&').reduce((acc, pair) => {
    const [key, value] = pair.split('=');
    acc[key] = value;
    return acc;
}, {});
console.log(params); // { key: 'value', key2: 'value2' }

24. 求陣列的眾數(一個陣列中出現最多的數字):

const numbers = [1, 2, 3, 2, 4, 3, 5, 3];
const mode = numbers.reduce((acc, num) => {
    acc[num] = (acc[num] || 0) + 1;
    if (!acc.mode || acc[num] > acc[acc.mode]) {
        acc.mode = num;
    }
    return acc;
}, {}).mode;
console.log(mode); // 3

25. 轉換為首字母大寫的字串:

const words = ['hello', 'world'];
const capitalizedWords = words.reduce((acc, word) => {
    acc.push(word.charAt(0).toUpperCase() + word.slice(1));
    return acc;
}, []);
console.log(capitalizedWords); // ['Hello', 'World']

26.合併重複的資料項目:

const data = [
    { id: 1, value: 10 },
    { id: 2, value: 20 },
    { id: 1, value: 5 }
];
const combined = data.reduce((acc, item) => {
    const existing = acc.find(entry => entry.id === item.id);
    if (existing) {
        existing.value += item.value;
    } else {
        acc.push({ ...item });
    }
    return acc;
}, []);
console.log(combined); // [{ id: 1, value: 15 }, { id: 2, value: 20 }]

27.建立資料的階層結構(可用於建立樹狀選單):

const flat = [
    { id: 1, parent: null },
    { id: 2, parent: 1 },
    { id: 3, parent: 1 },
    { id: 4, parent: 3 }
];
const tree = flat.reduce((acc, item) => {
    if (item.parent === null) {
        acc.push(item);
    } else {
        const parent = flat.find(entry => entry.id === item.parent);
        parent.children = parent.children || [];
        parent.children.push(item);
    }
    return acc;
}, []);
console.log(tree);
//[
//  {
//    "id": 1,
//    "parent": null,
//    "children": [
//      {
//        "id": 2,
//        "parent": 1
//      },
//      {
//        "id": 3,
//        "parent": 1,
//        "children": [
//          {
//            "id": 4,
//            "parent": 3
//          }
//        ]
//      }
//    ]
//  }
//]

28.建立資料的階層結構 (更深層次):

const flat = [
    { id: 1, parent: null },
    { id: 2, parent: 1 },
    { id: 3, parent: 2 },
    { id: 4, parent: 3 }
];
const toTree = (items, parent) => items.reduce((acc, item) => {
    if (item.parent === parent) {
        const children = toTree(items, item.id);
        if (children.length) item.children = children;
        acc.push(item);
    }
    return acc;
}, []);
console.log(toTree(flat, null));
//[
//  {
//    "id": 1,
//    "parent": null,
//    "children": [
//      {
//        "id": 2,
//        "parent": 1,
//        "children": [
//          {
//            "id": 3,
//            "parent": 2,
//            "children": [
//              {
//                "id": 4,
//                "parent": 3
//              }
//            ]
//          }
//        ]
//      }
//    ]
//  }
//]

29. 連續運算:

const operations = [
    { type: 'add', value: 5 },
    { type: 'multiply', value: 3 },
    { type: 'subtract', value: 2 }
];
const result = operations.reduce((acc, op) => {
    if (op.type === 'add') return acc + op.value;
    if (op.type === 'multiply') return acc * op.value;
    if (op.type === 'subtract') return acc - op.value;
    return acc;
}, 0);
console.log(result); // 13

30. 反轉陣列:

const numbers = [1, 2, 3, 4, 5];
const reversed = numbers.reduce((acc, num) => [num, ...acc], []);
console.log(reversed); // [5, 4, 3, 2, 1]

31. 移除陣列中的偽值(0, null, false, undefined...):

const values = [0, 1, false, null, "hello", undefined, 2];
const truthyValues = values.reduce((acc, value) => {
    if (value) {
        acc.push(value);
    }
    return acc;
}, []);
console.log(truthyValues); // [1, "hello", 2]

32. 計算陣列中數值的變異數(變異數是一個統計學上的指標,用來度量數據分散的程度,或者說數據的波動大小。):

  1. const numbers = [1, 2, 3, 4, 5];
    這裡我們有一個數字陣列 numbers。
  2. const avg = numbers.reduce((acc, num) => acc + num, 0) / numbers.length;
    這裡我們使用 reduce() 函式來計算 numbers 陣列的平均值。累加器 acc 存儲目前的總和,num 是當前的數字。初始化值為 0。計算完總和後,我們再除以數字陣列的長度來獲得平均值 avg。
  3. const variance = numbers.reduce((acc, num) => acc + Math.pow(num - avg, 2), 0) / numbers.length; 這裡再次使用 reduce() 函式來計算變異數。
  • 疊代每個數字,計算該數字和平均值的差(num - avg)。
  • 使用 Math.pow 函式來計算該差的平方。
  • 將這些平方和累加起來。
  • 最後,將累加的平方和除以數字陣列的長度,得到變異數。

簡單來說,這段程式碼首先計算了數字陣列的平均值,然後計算了每個數字與平均值的差的平方的平均值,即變異數。

const numbers = [1, 2, 3, 4, 5];
const avg = numbers.reduce((acc, num) => acc + num, 0) / numbers.length;
const variance = numbers.reduce((acc, num) => acc + Math.pow(num - avg, 2), 0) / numbers.length;
console.log(variance); // 2

33. 資料的連除:

const numbers = [100, 2, 5];
const result = numbers.reduce((acc, num) => acc / num);
console.log(result); // 10

#reduce #javascript #example







Related Posts

申請 Google 快速登入會員功能

申請 Google 快速登入會員功能

Linkedin Java 檢定題庫  try catch 流程

Linkedin Java 檢定題庫 try catch 流程

如何用 sequel pro 連到之前 xampp 的資料庫

如何用 sequel pro 連到之前 xampp 的資料庫


Comments